package se.webbzon.oschi01.worldobject.appearance;

import javax.media.j3d.Geometry;
import javax.media.j3d.GeometryArray;
import javax.media.j3d.TriangleStripArray;
import javax.vecmath.Point3d;
import javax.vecmath.TexCoord2f;

import com.sun.j3d.utils.geometry.GeometryInfo;
import com.sun.j3d.utils.geometry.NormalGenerator;

public class XYPlaneAppearance3D extends SimpleAppearance3D {
	
	// The geometry model of the xy-plane
	private static final Geometry model = createModel(1,1,false);
	
	// The geometry model of the back-faced xy-plane
	private static final Geometry modelBackfaced = createModel(1,1,true);

	/*============================================================
	Constructors
	============================================================*/
	
	/** Creates a new WorldObjectXYPlaneAppearance. The center of
	 * the plane will be placed in the origin and the plane will
	 * be stretched from (-0.5,-0.5,0) to (0.5,0.5,0). **/
	public XYPlaneAppearance3D() {
		this(0,0,false);
	}
	
	/** Creates a new WorldObjectXYPlaneAppearance. The center of
	 * the plane will be placed in the origin and the plane will
	 * be stretched from (-0.5,-0.5,0) to (0.5,0.5,0). See 
	 * WorldObjectSimpleAppearance for full description of the 
	 * attributes renderingOrder and simpleAppearanceProperties. **/
	public XYPlaneAppearance3D(	int renderingOrder,
								int simpleAppearanceProperties, boolean backfaced) {
		super(renderingOrder,simpleAppearanceProperties,backfaced ? modelBackfaced : model);
	}
	
	/*============================================================
	Private Methods
	============================================================*/
	
	/** Creates the geometry model. **/
	private static Geometry createModel(final double width, 
										final double height,
										final boolean backfaced) {
		final double w = width/2, h = height/2;
		final TriangleStripArray ta = new TriangleStripArray(4,
											GeometryArray.COORDINATES +
											GeometryArray.NORMALS + 
											GeometryArray.TEXTURE_COORDINATE_2,
											new int[] {4});
		
		// Create the corners of the plane
		final Point3d tl = new Point3d(-w,h,0);
		final Point3d bl = new Point3d(-w,-h,0);
		final Point3d tr = new Point3d(w,h,0);
		final Point3d br = new Point3d(w,-h,0);
		
		// Generate texture coordinates
		final TexCoord2f tl2 = new TexCoord2f(0,1);
		final TexCoord2f tr2 = new TexCoord2f(1,1);
		final TexCoord2f bl2 = new TexCoord2f(0,0);
		final TexCoord2f br2 = new TexCoord2f(1,0);
		
		// Create plane
		final Point3d[] plane;
		final TexCoord2f[] texCoord;
		if (backfaced) {
			final Point3d[] p = {bl,tl,br,tr};
			final TexCoord2f[] t = {bl2,tl2,br2,tr2};
			plane = p;
			texCoord = t;
		} else {
			final Point3d[] p = {bl,br,tl,tr};
			final TexCoord2f[] t = {bl2,br2,tl2,tr2};
			plane = p;
			texCoord = t;
		}
		
		ta.setCoordinates(0, plane);
		ta.setTextureCoordinates(0, 0, texCoord);
		
		// Generate normals
		final GeometryInfo g = new GeometryInfo(ta);
		final NormalGenerator ng = new NormalGenerator();
		ng.generateNormals(g);
					
		return g.getGeometryArray();
	}
	

}
